var LLBAND = [ 75, 60, 45, 30, 15, 0 ];

var LL2MC = [
		[ -0.0015702102444, 111320.7020616939, 1704480524535203,
				-10338987376042340, 26112667856603880, -35149669176653700,
				26595700718403920, -10725012454188240, 1800819912950474, 82.5 ],
		[ 0.0008277824516172526, 111320.7020463578, 647795574.6671607,
				-4082003173.641316, 10774905663.51142, -15171875531.51559,
				12053065338.62167, -5124939663.577472, 913311935.9512032, 67.5 ],
		[ 0.00337398766765, 111320.7020202162, 4481351.045890365,
				-23393751.19931662, 79682215.47186455, -115964993.2797253,
				97236711.15602145, -43661946.33752821, 8477230.501135234, 52.5 ],
		[ 0.00220636496208, 111320.7020209128, 51751.86112841131,
				3796837.749470245, 992013.7397791013, -1221952.21711287,
				1340652.697009075, -620943.6990984312, 144416.9293806241, 37.5 ],
		[ -0.0003441963504368392, 111320.7020576856, 278.2353980772752,
				2485758.690035394, 6070.750963243378, 54821.18345352118,
				9540.606633304236, -2710.55326746645, 1405.483844121726, 22.5 ],
		[ -0.0003218135878613132, 111320.7020701615, 0.00369383431289,
				823725.6402795718, 0.46104986909093, 2351.343141331292,
				1.58060784298199, 8.77738589078284, 0.37238884252424, 7.45 ] ];
var bT = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

function convertor(cn, co) {
	if (!cn || !co) {
		return;
	}
	var T = co[0] + co[1] * Math.abs(cn.lng);
	var cm = Math.abs(cn.lat) / co[9];
	var cp = co[2] + co[3] * cm + co[4] * cm * cm + co[5] * cm * cm * cm
			+ co[6] * cm * cm * cm * cm + co[7] * cm * cm * cm * cm * cm
			+ co[8] * cm * cm * cm * cm * cm * cm;
	T *= (cn.lng < 0 ? -1 : 1);
	cp *= (cn.lat < 0 ? -1 : 1);
	//alert(T);
	//alert(cp);
	return {"x":T,"y":cp};
}

function convertLL2MC(T) {
	var cm, co;
	T.lng = getLoop(T.lng, -180, 180);
	T.lat = getRange(T.lat, -74, 74);
	cm = new bR(T.lng, T.lat);
	for ( var cn = 0; cn < LLBAND.length; cn++) {
		if (cm.lat >= LLBAND[cn]) {
			co = LL2MC[cn];
			break;
		}
	}
	if (!co) {
		for ( var cn = LLBAND.length - 1; cn >= 0; cn--) {
			if (cm.lat <= -LLBAND[cn]) {
				co = LL2MC[cn];
				break;
			}
		}
	}
	return convertor(T, co);
}

function getRange(cn, cm, T) {
	if (cm != null) {
		cn = Math.max(cn, cm);
	}
	if (T != null) {
		cn = Math.min(cn, T);
	}
	return cn;
}
function getLoop(cn, cm, T) {
	while (cn > T) {
		cn -= T - cm;
	}
	while (cn < cm) {
		cn += T - cm;
	}
	return cn;
}

function bD(co) {
	var cm = "";
	var cv, ct, cr = "";
	var cu, cs, cq, cp = "";
	var cn = 0;
	var T = /[^A-Za-z0-9\+\/\=]/g;
	if (!co || T.exec(co)) {
		return co
	}
	co = co.replace(/[^A-Za-z0-9\+\/\=]/g, "");
	do {
		cu = bT.indexOf(co.charAt(cn++));
		cs = bT.indexOf(co.charAt(cn++));
		cq = bT.indexOf(co.charAt(cn++));
		cp = bT.indexOf(co.charAt(cn++));
		cv = (cu << 2) | (cs >> 4);
		ct = ((cs & 15) << 4) | (cq >> 2);
		cr = ((cq & 3) << 6) | cp;
		cm = cm + String.fromCharCode(cv);
		if (cq != 64) {
			cm = cm + String.fromCharCode(ct);
		}
		if (cp != 64) {
			cm = cm + String.fromCharCode(cr);
		}
		cv = ct = cr = "";
		cu = cs = cq = cp = "";
	} while (cn < co.length);
	return cm;
}

function bR(T, cm) {
	if (isNaN(T)) {
		T = bD(T);
		T = isNaN(T) ? 0 : T;
	}
	if (typeof T == "string") {
		T = parseFloat(T);
	}
	if (isNaN(cm)) {
		cm = bD(cm);
		cm = isNaN(cm) ? 0 : cm;
	}
	if (typeof cm == "string") {
		cm = parseFloat(cm);
	}
	this.lng = T;
	this.lat = cm;
}